#! /usr/bin/python
# -*- coding: utf-8 -*-

# Конвертор словаря Бориса Кондратьева из текстового формата в формат Mobipocket.
import os
from u2palm import *

DIR_SOURCE 		= "./source/"
DIR_MOBI_XHTML	= "./mobi/xhtml/"
DIR_MOBI 		= "./mobi/"
DIR_PALM 		= "./palm/"
DIR_PALM_XHTML  = "./palm/xhtml/"

cx2eo = {u'cx':u'ĉ', u'Cx':u'Ĉ', u'gx':u'ĝ', u'Gx':u'Ĝ', u'hx':u'ĥ', u'Hx':u'Ĥ',
         u'jx':u'ĵ', u'Jx':u'Ĵ', u'sx':u'ŝ', u'Sx':u'Ŝ', u'ux':u'ŭ', u'Ux':u'Ŭ',
         u'--':u'―', ':(':'', 
         'vt':'<font color="#AA0000">vt</font>',
         'vn':'<font color="#AA0000">vn</font>',
         '+i':'<font color="#AA0000">+i</font>'}
         
gramatiko = {'a':'adjektivo', 'o':'substantivo', 'i':'verbo'}

RusaLetero = u"абвгдеёжзийклмнопрстуфхцчшщьыъэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЫЪЭЯ"

def deklinacii(vorto):
	"""
	Склонение по падежам и создание индекса по различным формам входного слова.
	На входе словарная форма слова: существительное в именительном падеж
	или глагол в неопределённой форме.
	
	Функция возвращает специальный код включающий все возможные формы слова
	для добавления в массив contents.
	"""
	
	radiko 	= vorto[:-1] # Получаем корень слова отбрасывая конечную букву
	finajxo = vorto[-1]  # Окончание слова
	
	if finajxo == 'i':	# Склонение глагола
		return u"""<idx:infl inflgrp="verbo">
<idx:iform name="preterito" value="%sis"/>
<idx:iform name="prezenco" value="%sas"/>
<idx:iform name="futuro" value="%sos"/>
<idx:iform name="imperativo" value="%su"/>
<idx:iform name="volitivo" value="%sus"/>
</idx:infl>""" % (radiko, radiko, radiko, radiko, radiko)

	elif finajxo == 'o':	# Склонение существительного
		return """<idx:infl inflgrp="substantivo">
<idx:iform name="elizio" value="%s"/>
<idx:iform name="pluralo" value="%soj"/>
<idx:iform name="akuzativo" value="%son"/>
<idx:iform name="pluralakuzativo" value="%sojn"/>
</idx:infl>""" % (radiko, radiko, radiko, radiko)

	elif finajxo == 'a':	# Склонение прилагательного
		return """<idx:infl inflgrp="adjektivo">
<idx:iform name="pluralo" value="%sj"/>
<idx:iform name="akuzativo" value="%sn"/>
<idx:iform name="pluralakuzativo" value="%sjn"/>
</idx:infl>""" % ( vorto, vorto, vorto )

	elif finajxo == 'j':
		return """<idx:infl inflgrp="pluralo">
<idx:iform name="akuzativo" value="%sn"/>
</idx:infl>""" % radiko

	# Если входное слово имеет окончание отличное от {o,i,a,j} то не склоняем
	return ''

def kreiIndekso(vorto, radiko):
	"""
	Создание индексов для Mobipocket.
	На входе получаем строчку полученную из [...]
	Формируемый xHTML код добавляем в массив contents.
	"""

	indekso = ''
	vortoj = vorto.split(', ')
	out = []
	
	for x in vortoj:
		indekso = x.replace(u' III','').replace(u' II', '').replace(u' I', u'')
		if len(indekso) < 2: return ''

		indekso = indekso.replace('~', radiko).replace('/','').replace('|','')
		indekso = indekso.replace('(', '').replace(')', '').strip()

		out.append('\n<idx:orth "value = "%s">\n' % indekso)
		# Добавляем в индексы варианты склонения слова
		if len(indekso) > 1 and indekso.find('-') < 0:
			out.append(deklinacii(indekso))
  		out.append('</idx:orth>')
        	
	return ''.join(out)

def kreiArtikon(s):
	"""
	Создание отдельной словарной статьи.
	"""

	contents = ['<p> ']
	isKursivo = False
	bazo = ""
	indekso = ""
	
	for line in s.splitlines():
		#line = line.strip()
		
		if len(line) > 0 and line[0:3] == '200':
			line = ' '
		# Если в начале строки ключевое слово, то создаём индекс
		elif len(line) > 0 and line[0] == '[':
			# Выделяем словарное эсперанто-слово
			vorto = line[1:line.find(']')]
			# Определяем базовую часть слова для подстановки в слова с тильдой
			if vorto.find('|') > 0: bazo = vorto[:line.find('|')]
			elif vorto.find('~') < 0 and len(bazo) < 1: bazo = vorto
			
			indekso = kreiIndekso(vorto, bazo)
			contents.append(indekso)
		else: contents.append(' ')

		isStrike = False
		contents.append(' ')
		for c in line:
			if c == "[": contents.append("<b>")
			elif c == ']': contents.append("</b>")
			elif c == '_':
				isKursivo = not isKursivo
				if isKursivo: contents.append("<i>")
				else: contents.append("</i>")
			elif c == '{': contents.append("<small>")
			elif c == '}': contents.append("</small>")
			elif c == '/': contents.append(u'·')
			elif c == '|': contents.append(u'▪')
			elif c == '`': isStrike = True
			elif c == '<': None
			elif c == '>': None
			elif c == '\t': contents.append(' ')
			elif c == '@': contents.append(u'◊')
			else:
				contents.append(c)
				if isStrike:
					contents.append(u"́")
					isStrike = False

	# Закрываем определение последнего слова
	contents.append('</p>\n')
	
	if len(indekso) > 1:
		return '<idx:entry name="vortaro">%s</idx:entry>' % ''.join(contents)
	else : return ''.join(contents)

def kreiDosieron(nomo):
	"""
	Создание на основе исходного текстового файла из каталога DIR_SOURCE
	файла в формате XHTML для Mobipocket Reader. Получаемый файл сохраняется
	в каталоге DIR_MOBI_XHTML
	"""
	print "Faras dosieron: ", nomo

	# Заголовок файла XHTML
	out = [u"""<html><head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title>Esperanta-rusa vortaro</title></head><body>"""]

	# Считываем исходный текстовый файл, разбивая на словарные статьи,
    # разделённые двойным переводом каретки.
	data = open(DIR_SOURCE + '%s.txt'%nomo,'r').read().decode('cp1251').split("\n\n")

	# Удаляем первую строчку если она начинается с символа доллара.
	if data[0][0] == '$': data[0:1] = []

    # Перебираем все словарные статьи создавая нужную разметку XTML
	for i in data:
		out.append(unicode(kreiArtikon(i)))

	# Добавляем окончание для файла XHTML
	out.append(u'</body></html>')
	
    # Заменяем все эсперанто буквы в формате CX их аналогом в юникоде.
	xhtml = ''.join(out)
	for c in cx2eo: xhtml = xhtml.replace(c, cx2eo[c])
	
	# Записываем файл в формате xHTML
	open(DIR_MOBI_XHTML + '%s.html'%nomo,'w').write(xhtml.encode('utf8'))
	return None

def main():
	for fileName in os.listdir ( DIR_SOURCE ):
		if fileName[0] == '.' : continue
		if fileName[-4:] == '.txt' : kreiDosieron(fileName[:-4])
	unicode2palm(DIR_MOBI, DIR_PALM)
	unicode2palm(DIR_MOBI_XHTML, DIR_PALM_XHTML)
	return None
main()
